use async_trait::async_trait;
use rustcloud_core::{ServiceInstance, ServiceResult, ServiceError, ServiceRegistry};
use crate::{HealthCheckManager, HealthCheckState};
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::time::{Duration, SystemTime};
use tokio::sync::RwLock;
use tokio::time::{interval, sleep};
use tracing::{error, warn, info, debug};

/// 自动摘除策略
#[derive(Debug, Clone)]
pub enum RemovalStrategy {
    /// 基于连续失败次数
    ConsecutiveFailures {
        /// 连续失败次数阈值
        threshold: u32,
    },
    /// 基于失败率
    FailureRate {
        /// 失败率阈值 (0.0-1.0)
        threshold: f64,
        /// 最小检查次数（避免样本过小）
        min_checks: u64,
    },
    /// 基于不健康持续时间
    UnhealthyDuration {
        /// 不健康持续时间阈值
        threshold: Duration,
    },
    /// 组合策略（满足任一条件即摘除）
    Combined {
        strategies: Vec<RemovalStrategy>,
    },
}

/// 自动摘除配置
#[derive(Debug, Clone)]
pub struct AutoRemovalConfig {
    /// 是否启用自动摘除
    pub enabled: bool,
    /// 摘除策略
    pub strategy: RemovalStrategy,
    /// 检查间隔
    pub check_interval: Duration,
    /// 摘除后的冷却时间（防止频繁摘除）
    pub cooldown_period: Duration,
    /// 是否允许摘除最后一个实例
    pub allow_remove_last_instance: bool,
    /// 最小保留实例数
    pub min_instances: usize,
}

impl Default for AutoRemovalConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            strategy: RemovalStrategy::ConsecutiveFailures { threshold: 5 },
            check_interval: Duration::from_secs(60),
            cooldown_period: Duration::from_secs(300), // 5分钟
            allow_remove_last_instance: false,
            min_instances: 1,
        }
    }
}

/// 摘除记录
#[derive(Debug, Clone)]
pub struct RemovalRecord {
    pub instance: ServiceInstance,
    pub removal_time: SystemTime,
    pub reason: String,
    pub health_state: HealthCheckState,
}

/// 自动摘除事件
#[derive(Debug, Clone)]
pub enum AutoRemovalEvent {
    /// 实例被摘除
    InstanceRemoved {
        instance: ServiceInstance,
        reason: String,
    },
    /// 摘除被跳过（如最后一个实例）
    RemovalSkipped {
        instance: ServiceInstance,
        reason: String,
    },
    /// 摘除失败
    RemovalFailed {
        instance: ServiceInstance,
        error: String,
    },
}

/// 自动摘除事件监听器
#[async_trait]
pub trait AutoRemovalEventListener: Send + Sync {
    async fn on_event(&self, event: AutoRemovalEvent);
}

/// 自动摘除管理器
pub struct AutoRemovalManager {
    config: AutoRemovalConfig,
    registry: Arc<dyn ServiceRegistry>,
    health_manager: Arc<HealthCheckManager>,
    removal_records: Arc<RwLock<Vec<RemovalRecord>>>,
    last_removal_times: Arc<RwLock<HashMap<String, SystemTime>>>,
    event_listeners: Arc<RwLock<Vec<Arc<dyn AutoRemovalEventListener>>>>,
    running_tasks: Arc<RwLock<HashMap<String, tokio::task::JoinHandle<()>>>>,
}

impl AutoRemovalManager {
    pub fn new(
        config: AutoRemovalConfig,
        registry: Arc<dyn ServiceRegistry>,
        health_manager: Arc<HealthCheckManager>,
    ) -> Self {
        Self {
            config,
            registry,
            health_manager,
            removal_records: Arc::new(RwLock::new(Vec::new())),
            last_removal_times: Arc::new(RwLock::new(HashMap::new())),
            event_listeners: Arc::new(RwLock::new(Vec::new())),
            running_tasks: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 添加事件监听器
    pub async fn add_event_listener(&self, listener: Arc<dyn AutoRemovalEventListener>) {
        let mut listeners = self.event_listeners.write().await;
        listeners.push(listener);
    }

    /// 启动自动摘除监控
    pub async fn start_monitoring(&self, service_name: String) -> ServiceResult<()> {
        if !self.config.enabled {
            debug!("Auto removal is disabled for service: {}", service_name);
            return Ok(());
        }

        let task_key = service_name.clone();
        
        // 检查是否已经在监控
        {
            let tasks = self.running_tasks.read().await;
            if tasks.contains_key(&task_key) {
                return Err(ServiceError::ConfigurationError(
                    format!("Already monitoring service: {}", service_name)
                ));
            }
        }

        let config = self.config.clone();
        let registry = self.registry.clone();
        let health_manager = self.health_manager.clone();
        let removal_records = self.removal_records.clone();
        let last_removal_times = self.last_removal_times.clone();
        let event_listeners = self.event_listeners.clone();
        let service_name_clone = service_name.clone();

        let task = tokio::spawn(async move {
            let mut check_interval = interval(config.check_interval);
            
            loop {
                check_interval.tick().await;
                
                match Self::check_and_remove_unhealthy_instances(
                    &service_name_clone,
                    &config,
                    &registry,
                    &health_manager,
                    &removal_records,
                    &last_removal_times,
                    &event_listeners,
                ).await {
                    Ok(_) => {},
                    Err(e) => {
                        error!("Error during auto removal check for service {}: {}", service_name_clone, e);
                    }
                }
            }
        });

        // 保存任务句柄
        {
            let mut tasks = self.running_tasks.write().await;
            tasks.insert(task_key, task);
        }

        info!("Started auto removal monitoring for service: {}", service_name);
        Ok(())
    }

    /// 停止自动摘除监控
    pub async fn stop_monitoring(&self, service_name: &str) {
        let mut tasks = self.running_tasks.write().await;
        if let Some(task) = tasks.remove(service_name) {
            task.abort();
            info!("Stopped auto removal monitoring for service: {}", service_name);
        }
    }

    /// 检查并摘除不健康的实例
    async fn check_and_remove_unhealthy_instances(
        service_name: &str,
        config: &AutoRemovalConfig,
        registry: &Arc<dyn ServiceRegistry>,
        health_manager: &Arc<HealthCheckManager>,
        removal_records: &Arc<RwLock<Vec<RemovalRecord>>>,
        last_removal_times: &Arc<RwLock<HashMap<String, SystemTime>>>,
        event_listeners: &Arc<RwLock<Vec<Arc<dyn AutoRemovalEventListener>>>>,
    ) -> ServiceResult<()> {
        // 获取服务的所有实例
        let instances = registry.discover(service_name).await?;
        
        if instances.is_empty() {
            debug!("No instances found for service: {}", service_name);
            return Ok(());
        }

        // 获取所有健康状态
        let health_states = health_manager.get_all_health_states().await;
        
        let mut candidates_for_removal = Vec::new();
        
        for instance in &instances {
            let instance_key = format!("{}:{}:{}", instance.service_id, instance.host, instance.port);
            
            // 检查是否在冷却期内
            {
                let last_removal_times = last_removal_times.read().await;
                if let Some(last_removal) = last_removal_times.get(&instance_key) {
                    if last_removal.elapsed().unwrap_or(Duration::MAX) < config.cooldown_period {
                        debug!("Instance {} is in cooldown period, skipping removal check", instance_key);
                        continue;
                    }
                }
            }
            
            // 获取健康状态
            if let Some(health_state) = health_states.get(&instance_key) {
                if Self::should_remove_instance(&config.strategy, health_state) {
                    candidates_for_removal.push((instance.clone(), health_state.clone()));
                }
            }
        }

        // 检查是否允许摘除
        let healthy_instances_count = instances.len() - candidates_for_removal.len();
        
        for (instance, health_state) in candidates_for_removal {
            let instance_key = format!("{}:{}:{}", instance.service_id, instance.host, instance.port);
            
            // 检查最小实例数限制
            if healthy_instances_count < config.min_instances {
                let event = AutoRemovalEvent::RemovalSkipped {
                    instance: instance.clone(),
                    reason: format!("Would violate minimum instances limit ({})", config.min_instances),
                };
                Self::notify_listeners(&event_listeners, event).await;
                continue;
            }
            
            // 检查是否允许摘除最后一个实例
            if instances.len() == 1 && !config.allow_remove_last_instance {
                let event = AutoRemovalEvent::RemovalSkipped {
                    instance: instance.clone(),
                    reason: "Last instance removal not allowed".to_string(),
                };
                Self::notify_listeners(&event_listeners, event).await;
                continue;
            }
            
            // 执行摘除
            match registry.deregister(instance.clone()).await {
                Ok(()) => {
                    let reason = Self::get_removal_reason(&config.strategy, &health_state);
                    
                    // 记录摘除
                    {
                        let mut records = removal_records.write().await;
                        records.push(RemovalRecord {
                            instance: instance.clone(),
                            removal_time: SystemTime::now(),
                            reason: reason.clone(),
                            health_state: health_state.clone(),
                        });
                    }
                    
                    // 更新最后摘除时间
                    {
                        let mut last_times = last_removal_times.write().await;
                        last_times.insert(instance_key, SystemTime::now());
                    }
                    
                    // 停止健康检查
                    health_manager.stop_health_check(&instance).await;
                    
                    warn!("Auto removed unhealthy instance: {} ({})", instance, reason);
                    
                    let event = AutoRemovalEvent::InstanceRemoved {
                        instance: instance.clone(),
                        reason,
                    };
                    Self::notify_listeners(&event_listeners, event).await;
                }
                Err(e) => {
                    error!("Failed to remove instance {}: {}", instance, e);
                    
                    let event = AutoRemovalEvent::RemovalFailed {
                        instance: instance.clone(),
                        error: e.to_string(),
                    };
                    Self::notify_listeners(&event_listeners, event).await;
                }
            }
        }

        Ok(())
    }

    /// 检查实例是否应该被摘除
    fn should_remove_instance(strategy: &RemovalStrategy, health_state: &HealthCheckState) -> bool {
        match strategy {
            RemovalStrategy::ConsecutiveFailures { threshold } => {
                !health_state.is_healthy && health_state.consecutive_failures >= *threshold
            }
            RemovalStrategy::FailureRate { threshold, min_checks } => {
                if health_state.total_checks < *min_checks {
                    return false;
                }
                
                let failure_rate = health_state.total_failures as f64 / health_state.total_checks as f64;
                !health_state.is_healthy && failure_rate >= *threshold
            }
            RemovalStrategy::UnhealthyDuration { threshold } => {
                if health_state.is_healthy {
                    return false;
                }
                
                // 简化：使用最后检查时间作为不健康开始时间的近似
                health_state.last_check_time.elapsed().unwrap_or(Duration::ZERO) >= *threshold
            }
            RemovalStrategy::Combined { strategies } => {
                strategies.iter().any(|s| Self::should_remove_instance(s, health_state))
            }
        }
    }

    /// 获取摘除原因描述
    fn get_removal_reason(strategy: &RemovalStrategy, health_state: &HealthCheckState) -> String {
        match strategy {
            RemovalStrategy::ConsecutiveFailures { threshold } => {
                format!("Consecutive failures: {} (threshold: {})", 
                       health_state.consecutive_failures, threshold)
            }
            RemovalStrategy::FailureRate { threshold, min_checks: _ } => {
                let failure_rate = health_state.total_failures as f64 / health_state.total_checks as f64;
                format!("High failure rate: {:.2}% (threshold: {:.2}%)", 
                       failure_rate * 100.0, threshold * 100.0)
            }
            RemovalStrategy::UnhealthyDuration { threshold } => {
                let duration = health_state.last_check_time.elapsed().unwrap_or(Duration::ZERO);
                format!("Unhealthy duration: {:?} (threshold: {:?})", duration, threshold)
            }
            RemovalStrategy::Combined { strategies: _ } => {
                "Multiple criteria met".to_string()
            }
        }
    }

    /// 通知事件监听器
    async fn notify_listeners(
        listeners: &Arc<RwLock<Vec<Arc<dyn AutoRemovalEventListener>>>>,
        event: AutoRemovalEvent,
    ) {
        let listeners = listeners.read().await;
        for listener in listeners.iter() {
            listener.on_event(event.clone()).await;
        }
    }

    /// 获取摘除记录
    pub async fn get_removal_records(&self) -> Vec<RemovalRecord> {
        self.removal_records.read().await.clone()
    }

    /// 清理过期的摘除记录
    pub async fn cleanup_old_records(&self, max_age: Duration) {
        let mut records = self.removal_records.write().await;
        let now = SystemTime::now();
        
        records.retain(|record| {
            now.duration_since(record.removal_time).unwrap_or(Duration::ZERO) < max_age
        });
        
        // 同时清理过期的最后摘除时间记录
        let mut last_times = self.last_removal_times.write().await;
        last_times.retain(|_, time| {
            now.duration_since(*time).unwrap_or(Duration::ZERO) < max_age
        });
    }

    /// 停止所有监控任务
    pub async fn shutdown(&self) {
        let mut tasks = self.running_tasks.write().await;
        for (service_name, task) in tasks.drain() {
            task.abort();
            info!("Stopped auto removal monitoring for service: {}", service_name);
        }
    }
}

/// 默认事件监听器实现（日志输出）
pub struct LoggingEventListener;

#[async_trait]
impl AutoRemovalEventListener for LoggingEventListener {
    async fn on_event(&self, event: AutoRemovalEvent) {
        match event {
            AutoRemovalEvent::InstanceRemoved { instance, reason } => {
                info!("🗑️ Auto removed instance: {} - {}", instance, reason);
            }
            AutoRemovalEvent::RemovalSkipped { instance, reason } => {
                debug!("⏭️ Skipped removal for instance: {} - {}", instance, reason);
            }
            AutoRemovalEvent::RemovalFailed { instance, error } => {
                error!("❌ Failed to remove instance: {} - {}", instance, error);
            }
        }
    }
}